Comunicatia intre procese
1. Cutii postale
In unele cazuri interactiunea intre procese cere efectuarea unui schimb de date, suplimentar semnalelor de sincronizare, intre procesele care coopereaza. Solutia clasica a acestor probleme foloseste un tampon pentru mesaje (message buffer), numit si cutie postala (mailbox). Cutia postala reprezinta o extensie a semafoarelor, deoarece ea permite asocierea unui set de date, numit mesaj, fiecarei operatii de semnalizare.
O cutie postala se comporta in acelasi mod cu un semafor, cu exceptia manipularii mesajelor. In consecinta, se folosesc aceleasi reguli de sincronizare si aceiasi invarianti. Operatiile trebuie modificate pentru a se putea manipula mesajele care se transmit sau se receptioneaza. Noile operatii sint send(x,m) si receive(x,m), corespunzind lui P si respectiv, V. x este identificatorul cutiei postale iar m este cel al mesajului.
Cind se efectueaza o operatie de tip send, mesajul se insereaza in cutia postala, daca aceasta nu este plina. Cind se efectueaza o operatie de tip receive se extrage primul mesaj din cutia postala, daca aceasta nu este vida. In mod obisnuit, ordonarea mesajerlor in cutia postala este similara cu cea a unei stive de tip FIFO: operatia receive extrage din stiva cel mai vechi mesaj pe care aceasta il contine. Sint posibile si organizari care asigneaza prioritati mesajelor continute de cutia postala.
2. Implemenatrea cutiilor postale

Implementarea cutiilor postale este similara cu cea pentru semafoare, la care se adauga facilitatile legate de manpularea mesajelor. In continuare se sugereaza un mod de realizare:

     mailbox = record
          v   : lockvar;
          n,i : integer;
          buffer:    message;
          waitqueue:  processdescriptor;
     end;

     procedure send(x:mailbox, m:message);
     begin
       entercr(x.v);
       if x.v = x.c then
         begin
           introducerea mesajului m in tampon;
extragerea descriptorului procesului curent din multimea proceselor de executat;
inserarea lui in sirul de asteptare;
exitcr(x.v);
realocarea utilizarii CPU;
         end
       else
         begin
           if x.c=0 and x.waitqueue<> nil then
             begin
               extragerea unui descriptor de proces din sirul de                asteptare;
asocierea mesajului m cu procesul extern;
exitcr(x.v);
inserarea descriptorului procesului in multimea de procese de executat;
realocarea utilizarii CPU;
             end
           else 
             begin
               inserarea mesajului m in tampon;
               x.c := x.c + 1;
               exitcr(x.v);
             end
         end;

     procedure receive(x:mailbox, m:message);
     begin        entercr(x.v);
       if x.c=0 then
         begin
           extragerea descriptorului procesului curent din setul de procese de executat;inserarea lui in sirul de asteptare;
exitcr(x.v);
realocarea utilizarii CPU;
(aceasta se executa la reluarea procesului,deoarece exista mesaj)
copierea in m a mesajului asociat procesului;
         end
       else
         begin
extragerea mesajului din tampon si copierea lui in m; 
if x.c=x.n and x.waitqueue<> nil then
             begin
               extragerea unui descriptor de proces din sirul de                asteptare;
exitcr(x.v);
    introducerea descriptorului extras in multimea     proceselor de executat;
realocarea utilizarii CPU;
             end
           else 
             begin
               x.n := x.n   1;
               exitcr(x.v);
             end
         end;

In cadrul procedurii send mesajul este introdus in cutia postala chiar daca aceasta este considerata plina, deoarece structura de lista inlantuita nu impune o limitare a numarului de measje ce se pot memora. Conditia "buffer full" (tamponul plin) se foloseste doar pentru sincronizarea intre procese.
Un fapt important este acela ca procedura send este asociata cu un mesaj catre un proces atunci cind tamponul este vid. Necesitatea acestei modalitati de lucru este impusa de faptul ca, daca un proces care asteapta un mesaj este activat, executia sa incepe doar dupa o lunga durata de timp, daca prioritatea sa este redusa. In acest caz s ar putea intimpla ca alte operatii send sa aiba loc intre timp si alte procese, de prioritate superioara, sa fie activate si executate. Deci procesele de prioritate ridicata pot sa isi extraga mesajele inainte ca cele de prioritate redusa sa fie activate. In acest mod, se pastreaza ordinea de receptionare a mesajelor, pentru ca mesajul este extras cind procesul in asteptare este deblocat. Pentru a lega mesajul si procesul se poate folosi un pointer adecvat catre descriptorul procesului. 3.7.3. Sincronizarea proceselor
Se considera o unica linie tehnologica compusa din doua masini unelte, masina 1 si masina 2, si un unic tampon B de capacitate c, plasat intre cele doua masini. Operatia este astfel organizata incit masina 1 primeste o piesa si o prelucreaza. Cind operatia este completa, masina 1 plaseaza piesa in tampon, cu conditia ca acesta sa nu fie plin, dupa care obtine o noua piesa, daca este disponibila, si repeta aceeasi operatie. Cind masina 1 incearca sa plaseze o piesa in tamponul plin functionarea sa este blocata, pentru ca trebuie sa astepte pina cind este spatiu in acesta, ceea ce ii permite sa depuna piesa prelucrata si sa se ocupe de o alta.
In cealalta parte a tamponului, masina 2 se comporta intr un mod similar. Intii ea incearca sa obtina din tampon o piesa pentru prelucrare. Daca acesta nu este gol, masina 2 extrage o piesa, pe care o prelucreaza; in caz contrar asteapta pina cind tamponul contine cel putin o piesa.
Cele doua masini sint comandate de doua procese diferite, A si B, executate de catre aceeasi unitate centrala de prelucrare. Se pune problema sincronizarii, pe baza continutului tamponului, a functionarii lor.
In exemplul ales, care presupune identitatea pieselor prelucrate, starea tamponului poate fi convenabl reprezentata printr un numarator indicind numarul de piese pe care le contine. Intrucit ceea ce afecteaza functionarea masinilor sint valorile extreme ale continutului numaratorului, cae mai buna metoda de sincronizare pare aceea folosind semafoare. In continuare se indica o schita de realizare, in acelasi limbaj pseudo Pascal, in care x este un semafor cu capacitatea k unitati, initializat cu numarul de piese din tampon la inceputul operatiei.
     schita procesului A
     .
     .
     .
     while true do
       begin
         obtine o noua piesa;
         prelucreaza piesa;
         P(x);
         pune piesa in tampon;
       end;
     .
     .
     .

      schita procesului B
     .
     .
     .
     while true do
       begin
         V(x);
         obtine o piesa din tampon;
         prelucreaza piesa;
         pune piesa in tamponul de iesire;
       end;
     .
     .
     .

Operatia P blocheaza procesul A cind tamponul este plin, in timp ce operatia V blocheaza procesul B cind acesta este vid. Pe de alta parte, P porneste procesul B cind tamponul este gol si B asteapta sa prelucreze, iar V va porni procesul A cind tamponul este plin si A asteapta sa stocheze o piesa in tampon.


4. Comunicatia intre procese
Exemplul precedent poate fi modificat pentru a demonstra ca doar semafoarele nu sint suficiente pentru implementarea simpla  a sincronizari. In exemplul modificat se considera ca piesele nu sint identice. Ele fac parte din patru clase distincte, identificate prin numerele 1,2,3,4. De asemenea, se impune cerinta suplimentara ca piesele sa fie prelucrate in aceeasi secventa de catre ambele masini.
Sincronizarea presupune si un schimb de date intre procesele care coopereaza, intrucit informatia vehiculata nu indica doar introducerea in tampon a unei piese sau extragerea unei piese din acesta. Orice semnal de inserare trebuie sa contina date identificind tipul piesei, care trebuie citite cind piesa este extrasa.
Aceste considerente recomanda folosirea unei cutii postale, in care mesajele sint intregi indicind tipul piesei asociate. Cele doua schite de proces se modifica si aspectul lor este descris mai jos.
     schita procesului A
     .
     .
     .
     while true do
       begin
         obtine o piesa si transcrie in m tipul ei;          case m of
           1: prelucrare de tip 1;
           2: prelucrare de tip 2;
           3: prelucrare de tip 3;
           4: prelucrare de tip 4;
         end;
         send(x,m);
         pune piesa in tampon;
       end;
     .
     .
     .
     schita procesului B
     while true do
       begin
         receive(x,m);
         case m of
           1: prelucrare de tip 1;
           2: prelucrare de tip 2;
           3: prelucrare de tip 3;
           4: prelucrare de tip 4;
         end;
         pune piesa in tamponul de iesire;
       end;
         
Sincronizarea se efectueaza la fel ca in cazul precedent, dar procesul A transfera catre B informatii privind tipul piesei. Daca organizarea cutiei postale este de tipul FIFO, piesele sint prelucrate in aceeasi secventa de catre ambele masini, deoarece procesul B primeste mesajele in ordinea in care ele au fost emise de catre A.
Nu s au facut ipoteze privind vitezele relative ale celor doua procese, sau asupra sosirii pieselor la masina 1, element esential in intregul proces de productie. Acest fapt garanteaza ca solutia bazata pe semafoare sau cutii postale este corecta indiferentde viteza de executie.
Mai exista si alte posibile extensii ale exemplului, printre care si considerarea situatiei in care mai multe masini identice executa munca masinii 1 si plaseaza rezultatele in acelasi tampon, din care mai multe masini, operind identic cu masina 2, extrag din tampon in vederea prelucrarii rezultatele existente. In acest caz este suficient a dispune de un singur proces A pentru comanda unei masini de tipul 1, si de un singur proces B pentru comanda masinii de tipul 2. Sincronizarea se poate face, de asemenea, cu ajutorul semafoarelor si a cutiilor postale. Se deduce ca mecanismele descrise functioneaza corect si in cazul unor producatori si consumatori multipli.
